home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / vol6n19.arc / CTYPE.ASM next >
Assembly Source File  |  1987-10-31  |  23KB  |  564 lines

  1. ;CTYPE.COM for the IBM Personal Computer - 1987 by Jeff Prosise
  2.  
  3. bios_data     segment at 40h
  4.               org 60h
  5. cursor_mode   dw ?                          ;cursor scan lines
  6.               org 63h
  7. addr_6845     dw ?                          ;CRT Controller base address
  8.               org 87h
  9. ega_info      db ?                          ;EGA info byte
  10. bios_data     ends
  11.  
  12. ;----------------------------------------------------------------------
  13. code          segment para public 'code'
  14.               assume cs:code,ds:code
  15.               org 100h
  16. begin:        jmp ctype
  17.  
  18. program       db 'CTYPE 1.0 '
  19. copyright     db '(c) 1987 Ziff Communications Co.',1Ah
  20. author        db 'Jeff Prosise'
  21.  
  22. header        db 'PC Magazine Cursor Definition Utility',0
  23. subheader     db 'CTYPE /',0
  24. footer1       db '< Use arrow keys to navigate grid >',0,0
  25.               db 'ENTER    : Select cursor and exit',0
  26.               db 'SPACEBAR : View cursor with text',0
  27. footer2       db '< Press SPACEBAR to return >',0,0
  28.               db 'A single line of sample text',0
  29. errmsg        db 13,10,'Illegal parameters',13,10,'$'
  30.  
  31. adapter       db 3                          ;0=MDA, 1=CGA, 2=EGA, 3=VGA
  32. points        label byte
  33. lpoints       dw 8                          ;scan lines per row (default=CGA)
  34. rows          db 24                         ;number of rows (default=CGA, MDA)
  35. columns       db ?                          ;number of video columns
  36. attr1         db 02h                        ;main video attribute
  37. attr2         db 1Fh                        ;auxiliary video attribute
  38. old_attr      db 0
  39. deltacol      db 2                          ;space between frame columns
  40. startcol      db ?                          ;first frame column
  41. vpage         db ?                          ;active video page
  42. textrow       db ?                          ;row where text footer begins
  43.  
  44. ;-----------------------------------------------------------------------------
  45. ;CTYPE is the main procedure.
  46. ;-----------------------------------------------------------------------------
  47. ctype         proc near
  48. ;
  49. ;Find the current color of the screen for clearing later.
  50. ;
  51.               mov ah,15                     ;get columns and page
  52.               int 10h
  53.               mov columns,ah                ;save them
  54.               mov vpage,bh
  55.  
  56.               mov ah,8                      ;save old screen colors
  57.               int 10h
  58.               mov old_attr,ah
  59.  
  60.               mov ax,bios_data              ;point ES to BIOS data area
  61.               mov es,ax
  62.               assume es:bios_data
  63. ;
  64. ;Determine what type of video adapter is active, whether video is color
  65. ;or monochrome, and how many scan lines make up each character box.
  66. ;
  67.               mov ax,1A00h                  ;check for a VGA
  68.               int 10h
  69.               cmp al,1Ah                    ;is AL set to 1Ah?
  70.               jne check_ega                 ;no, then no VGA present
  71.               cmp bl,7                      ;test for active VGA
  72.               jb check_ega
  73.               cmp bl,8
  74.               ja check_ega
  75.               call SetVideoParms            ;determine rows and points
  76.               cmp bl,7                      ;reset attributes if monochrome
  77.               je mono
  78.               jmp short checkparm           ;done if video is color
  79.  
  80. check_ega:    dec adapter                   ;assume this is an EGA
  81.               mov ah,12h                    ;video function 12h
  82.               mov bl,10h                    ;subfunction - return EGA info
  83.               int 10h
  84.               cmp bl,10h                    ;did BL return unchanged?
  85.               je no_ega                     ;yes, then no EGA
  86.               test ega_info,8               ;is the EGA currently active?
  87.               jnz no_ega                    ;no, then continue the check
  88.               call SetVideoParms            ;determine rows and points
  89.               or bh,bh                      ;is BH zero?
  90.               jne mono                      ;no, then it's a mono system
  91.               jmp short checkparm           ;yes, then it's color
  92.  
  93. no_ega:       dec adapter                   ;assume this is a CGA
  94.               test addr_6845,40h            ;is bit 6 of the CRTC address set?
  95.               jnz checkparm                 ;yes, then it's a CGA
  96.               mov points,14                 ;no, then it's an MDA
  97.               dec adapter                   ;set ADAPTER to zero for MDA
  98. mono:         mov attr1,07h                 ;alter video parameters for mono
  99.               mov attr2,70h
  100. ;
  101. ;Check the command line for cursor definition parameters.
  102. ;
  103. checkparm:    push cs                       ;point ES to code segment
  104.               pop es
  105.               assume es:code
  106.               cld                           ;clear DF
  107.               mov di,82h                    ;point ES:DI to text of line
  108.               cmp byte ptr [di-2],2         ;at least 2 characters entered?
  109.               jb noparm                     ;no, then nothing was entered
  110.               mov cx,10                     ;check for slash character
  111.               mov al,'/'
  112.               repne scasb
  113.               jcxz noparm                   ;branch if command line is empty
  114.               mov cx,[di]                   ;get 2 characters after slash
  115.               and cx,0DFDFh                 ;capitalize them
  116.               sub cx,4141h                  ;then normalize them
  117.               cmp ch,points                 ;see if they're in range
  118.               jae parm_error
  119.               cmp cl,points
  120.               jae parm_error
  121. ;
  122. ;Set the cursor and exit.
  123. ;
  124.               xchg ch,cl                    ;swap CH and CL
  125.               mov al,points                 ;calculate ending scan line
  126.               sub al,cl
  127.               dec al
  128.               cmp ch,al                     ;make sure parameters are legal
  129.               ja parm_error
  130.               mov cl,al                     ;transfer scan line to CL
  131.               call SetCursorMode            ;set cursor shape
  132. cursor_exit:  mov ax,4C00h                  ;exit with ERRORLEVEL = 0
  133.               int 21h
  134. ;
  135. ;Command line parameters are out of range.  Print error message and exit.
  136. ;
  137. parm_error:   mov ah,9                      ;print error message
  138.               mov dx,offset errmsg
  139.               int 21h
  140.               mov ax,4C01h                  ;exit with ERRORLEVEL = 1
  141.               int 21h
  142. ;
  143. ;Create the cursor definition screen for interactive mode selection.
  144. ;
  145. noparm:
  146. ;              mov ah,15                     ;get columns and page
  147. ;              int 10h
  148. ;              mov columns,ah                ;save them
  149. ;              mov vpage,bh
  150.               cmp columns,80                ;at least 80 columns displayed?
  151.               jae col80                     ;yes, then branch
  152.               mov deltacol,1                ;no, then adjust for short display
  153.  
  154. col80:        call ClearScreen              ;clear the screen
  155.               mov ah,1                      ;hide the cursor
  156.               mov ch,20h
  157.               int 10h
  158.  
  159.               mov ax,0920h                  ;blank the screen header line
  160.               mov bl,attr2
  161.               mov bh,vpage
  162.               mov cl,columns
  163.               xor ch,ch
  164.               int 10h
  165.               mov si,offset header          ;display screen header
  166.               xor dh,dh
  167.               mov dl,columns
  168.               sub dl,37
  169.               shr dl,1
  170.               call WriteString
  171.               call DrawFrame                ;draw the cursor selection frame
  172.  
  173.               mov ah,2                      ;display 'CTYPE /XX' subheader
  174.               mov dh,2
  175.               mov dl,startcol
  176.               mov bl,attr1
  177.               mov si,offset subheader
  178.               call WriteString
  179. ;
  180. ;Position and display a 2-line underline cursor.
  181. ;
  182.               mov cl,points                 ;get number of scan lines
  183.               dec cl                        ;decrement it for ending line
  184.               mov ch,cl                     ;set starting line one higher
  185.               dec ch
  186.               jmp short display
  187. ;
  188. ;Enter a loop, polling the keyboard for keypresses.
  189. ;
  190. getkey:       mov ah,0                      ;get a keypress
  191.               int 16h
  192.               or al,al                      ;extended code?
  193.               je excode                     ;yes, then branch
  194.               cmp al,32                     ;SPACEBAR?
  195.               jne nospace
  196.               call ShowText                 ;show cursor with text
  197.               jmp short getkey              ;return for more
  198.  
  199. nospace:      cmp al,13                     ;ENTER key?
  200.               jne getkey                    ;no, then ignore keypress
  201.               call ClearScreen              ;clear screen and exit
  202.               jmp cursor_exit
  203.  
  204. excode:       cmp ah,72                     ;Up-arrow?
  205.               jne checklft
  206.               or ch,ch                      ;decrement starting scan line
  207.               jne ex1
  208.               mov ch,cl
  209.               jmp short display
  210. ex1:          dec ch
  211.               jmp short display
  212.  
  213. checklft:     cmp ah,75                     ;Left-arrow?
  214.               jne checkrt
  215.               inc cl                        ;increment ending scan line
  216.               cmp cl,points
  217.               jne display
  218.               mov cl,ch
  219.               jmp short display
  220.  
  221. checkrt:      cmp ah,77                     ;Right-arrow?
  222.               jne checkdn
  223.               cmp ch,cl                     ;decrement ending scan line
  224.               jne rt1
  225.               mov cl,points
  226.               dec cl
  227.               jmp short display
  228. rt1:          dec cl
  229.               jmp short display
  230.  
  231. checkdn:      cmp ah,80                     ;Down-arrow?
  232.               jne getkey                    ;no, then ignore the keypress
  233.               cmp ch,cl                     ;increment starting scan line
  234.               jne dn1
  235.               xor ch,ch
  236.               jmp short display
  237. dn1:          inc ch
  238.  
  239. display:      call ShowParm                 ;display command line parameters
  240.               call LocateCursor             ;reposition the cursor
  241.               call SetCursorMode            ;then display it in its new form
  242.               jmp short getkey              ;return to keyboard loop
  243. ctype         endp
  244.  
  245. ;-----------------------------------------------------------------------------
  246. ;SetVideoParms retrieves and stores the number of rows displayed and the
  247. ;number of scan lines per character.
  248. ;-----------------------------------------------------------------------------
  249. SetVideoParms proc near
  250.               push bx                       ;save BX
  251.               mov ax,1130h                  ;get scan line and row count
  252.               int 10h
  253.               mov rows,dl                   ;save them (rows - 1)
  254.               mov points,cl
  255.               pop bx                        ;restore BX
  256.               ret
  257. SetVideoParms endp
  258.  
  259. ;-----------------------------------------------------------------------------
  260. ;SetCursorMode sets the shape of the cursor.
  261. ;Entry:  CH,CL - beginning and ending scan lines
  262. ;-----------------------------------------------------------------------------
  263. SetCursorMode proc near
  264.               push cx                       ;save CX for screen location
  265.               cmp adapter,2                 ;is an EGA active?
  266.               jne scm1                      ;no, then branch
  267.               inc cl                        ;yes, then adjust ending line
  268.               cmp cl,points                 ;wrap around if necessary
  269.               jne scm0
  270.               xor cl,cl
  271.  
  272. scm0:         cmp ch,cl                     ;should this be a block cursor?
  273.               jne scm1                      ;no, then branch
  274.               mov cl,1Eh                    ;yes, then adjust ending scan line
  275.  
  276. scm1:         push es                       ;save ES
  277.               mov ax,bios_data
  278.               mov es,ax
  279.               assume es:bios_data
  280.               mov dx,addr_6845              ;get CRT Controller address
  281.               mov cursor_mode,cx            ;save definition in BIOS area
  282.               pop es                        ;restore ES
  283.               assume es:code
  284.  
  285.               mov al,10                     ;OUT CH and CL to cursor registers
  286.               out dx,al
  287.               inc dx
  288.               mov al,ch
  289.               out dx,al
  290.               dec dx
  291.               mov al,11
  292.               out dx,al
  293.               inc dx
  294.               mov al,cl
  295.               out dx,al
  296.               pop cx                        ;retrieve nominal cursor shape
  297.               ret
  298. SetCursorMode endp
  299.  
  300. ;-----------------------------------------------------------------------------
  301. ;ShowText displays the current cursor on a line of text.
  302. ;-----------------------------------------------------------------------------
  303. endcol        db ?                          ;ending column
  304.  
  305. ShowText      proc near
  306.  
  307.               push cx                       ;save cursor parameter
  308.               call ClearRegion              ;clear lower part of screen
  309.               mov si,offset footer2         ;display new footer
  310.               mov cx,3
  311.               call DrawFooter
  312.               mov ah,2                      ;home the cursor
  313.               dec dh
  314.               int 10h
  315.               mov endcol,dl                 ;calculate rightmost column
  316.               add endcol,27
  317.  
  318. input:        mov ah,0                      ;get a keystroke
  319.               int 16h
  320.               or al,al                      ;extended code?
  321.               je fkey                       ;yes, then branch
  322.  
  323.               cmp al,32                     ;SPACEBAR?
  324.               jne input                     ;no, then ignore it
  325.               call ClearRegion              ;restore main footer
  326.               mov si,offset footer1
  327.               mov cx,4
  328.               call DrawFooter
  329.               pop cx                        ;restore cursor parameter
  330.               call LocateCursor             ;restore cursor position
  331.               ret
  332.  
  333. fkey:         cmp ah,75                     ;Left-arrow?
  334.               jne fkey1
  335.               cmp dl,startcol               ;at left end of line?
  336.               je input                      ;yes, then don't move
  337.               dec dl                        ;move one character left
  338. fkey0:        mov ah,2
  339.               mov bh,vpage
  340.               int 10h
  341.               jmp short input               ;return for more
  342.  
  343. fkey1:        cmp ah,77                     ;Right-arrow?
  344.               jne input                     ;no, then ignore it
  345.               cmp dl,endcol                 ;at right end of line?
  346.               je input                      ;yes, then don't move
  347.               inc dl                        ;advance cursor
  348.               jmp short fkey0
  349. ShowText      endp
  350.  
  351. ;-----------------------------------------------------------------------------
  352. ;LocateCursor positions the cursor inside the selection frame.
  353. ;Entry:  CH,CL - starting and ending cursor scan lines
  354. ;-----------------------------------------------------------------------------
  355. LocateCursor  proc near
  356.               mov dh,ch                     ;calculate screen row from CH
  357.               add dh,4
  358.               mov dl,startcol               ;calculate column from CL
  359.               add dl,2
  360.               mov al,deltacol
  361.               add dl,al
  362.               inc al
  363.               mov bl,points
  364.               sub bl,cl
  365.               dec bl
  366.               mul bl
  367.               add dl,al
  368.               mov bh,vpage                  ;set video page number
  369.               mov ah,2                      ;position cursor
  370.               int 10h
  371.               ret
  372. LocateCursor  endp
  373.  
  374. ;-----------------------------------------------------------------------------
  375. ;ShowParm updates the display of the current cursor's /XX parameters.
  376. ;Entry:  CH,CL - starting and ending scan lines
  377. ;-----------------------------------------------------------------------------
  378. ShowParm      proc near
  379.               mov ah,2                      ;position the cursor
  380.               mov bh,vpage
  381.               mov dh,2
  382.               mov dl,startcol
  383.               add dl,7
  384.               int 10h
  385.               mov ah,0Eh                    ;write first character
  386.               mov al,ch
  387.               add al,41h
  388.               int 10h
  389.               mov ah,0Eh                    ;write second character
  390.               mov al,points
  391.               sub al,cl
  392.               add al,40h
  393.               int 10h
  394.               ret
  395. ShowParm      endp
  396.  
  397. ;-----------------------------------------------------------------------------
  398. ;DrawFrame draws the cursor definition frame.
  399. ;-----------------------------------------------------------------------------
  400. numpoints     dw ?                          ;counter for dots per line
  401. ;
  402. DrawFrame     proc near
  403.               mov al,points                 ;calculate length of top line
  404.               mov bl,deltacol
  405.               inc bl
  406.               mul bl
  407.               add ax,3
  408.               mov cx,ax                     ;transfer result to CX
  409.               mov bl,columns                ;calculate starting column number
  410.               sub bl,al
  411.               shr bl,1
  412.               mov startcol,bl
  413.  
  414.               mov ah,2                      ;position cursor for top line
  415.               mov dh,3
  416.               mov dl,startcol
  417.               mov bh,vpage
  418.               int 10h
  419.               mov ax,0920h                  ;blank out the top line
  420.               mov bl,attr2
  421.               int 10h
  422.  
  423.               mov cx,lpoints                ;fill in text of top line
  424.               mov dh,3
  425.               mov dl,startcol
  426.               add dl,deltacol
  427.               add dl,2
  428.               mov al,'A'
  429. drawloop1:    mov bl,al
  430.               mov ah,2
  431.               int 10h
  432.               mov ah,0Eh
  433.               mov al,bl
  434.               int 10h
  435.               add dl,deltacol
  436.               inc dl
  437.               mov al,bl
  438.               inc al
  439.               loop drawloop1
  440.  
  441.               mov cx,lpoints                ;then blank the vertical leg
  442.               mov dh,4
  443.               mov dl,startcol
  444.               mov bl,attr2
  445. drawloop2:    push cx
  446.               mov ah,2
  447.               int 10h
  448.               mov ax,0920h
  449.               mov cl,deltacol
  450.               inc cl
  451.               xor ch,ch
  452.               int 10h
  453.               inc dh
  454.               pop cx
  455.               loop drawloop2
  456.  
  457.               mov cx,lpoints                ;fill in the dots and text
  458.               mov numpoints,cx
  459.               mov dh,4
  460.               mov dl,startcol
  461.               inc dl
  462.               mov al,'A'
  463. drawloop3:    push cx
  464.               mov bl,al
  465.               mov ah,2
  466.               int 10h
  467.               mov al,bl
  468.               mov ah,0Eh
  469.               int 10h
  470.  
  471.               mov cx,numpoints              ;fill one grid line
  472. drawloop4:    mov ah,2
  473.               add dl,deltacol
  474.               inc dl
  475.               int 10h
  476.               mov ax,0EF9h
  477.               int 10h
  478.               loop drawloop4
  479.  
  480.               dec numpoints                 ;one less dot on next line
  481.               mov al,bl
  482.               inc al
  483.               inc dh
  484.               mov dl,startcol
  485.               inc dl
  486.               pop cx
  487.               loop drawloop3
  488.  
  489.               mov textrow,dh                ;store current row number
  490.               inc textrow
  491.               mov si,offset footer1         ;draw text footer
  492.               mov cx,4
  493.               call DrawFooter
  494.               ret
  495. DrawFrame     endp
  496.  
  497. ;-----------------------------------------------------------------------------
  498. ;DrawFooter writes a block of text below the selection frame.
  499. ;Entry:  CX - number of lines
  500. ;-----------------------------------------------------------------------------
  501. DrawFooter    proc near
  502.               mov dh,textrow                ;initialize cursor position
  503.               mov dl,startcol
  504.               mov bl,attr1                  ;set attribute
  505. drawloop5:    push cx                       ;enter loop
  506.               call WriteString              ;write one line
  507.               inc dh                        ;advance cursor
  508.               mov dl,startcol
  509.               pop cx
  510.               loop drawloop5                ;loop until done
  511.               ret
  512. DrawFooter    endp
  513.  
  514. ;-----------------------------------------------------------------------------
  515. ;WriteString writes an ASCIIZ text string to video memory.
  516. ;Entry:  DS:SI - string address
  517. ;        DH,DL - starting cursor address
  518. ;        BL    - attribute
  519. ;-----------------------------------------------------------------------------
  520. WriteString   proc near
  521.               mov ah,2                      ;position cursor
  522.               mov bh,vpage
  523.               int 10h
  524.               lodsb                         ;get a byte
  525.               or al,al                      ;is it the delimiter?
  526.               je ws1                        ;yes, then exit
  527.               mov ah,9                      ;no, then display it
  528.               mov cx,1
  529.               int 10h
  530.               inc dl                        ;advance the cursor
  531.               jmp short WriteString         ;loop until done
  532. ws1:          ret
  533. WriteString   endp
  534.  
  535. ;-----------------------------------------------------------------------------
  536. ;ClearScreen clears the display and homes the cursor.
  537. ;-----------------------------------------------------------------------------
  538. ClearScreen   proc near
  539.               mov ah,2                      ;home the cursor
  540.               xor dx,dx
  541.               mov bh,vpage
  542.               int 10h
  543.               xor cx,cx                     ;define upper right corner
  544. clear1:       mov dl,columns                ;define lower right corner
  545.               dec dl
  546.               mov dh,rows
  547.               mov bh,old_attr
  548.               mov ax,0600h                  ;video function 6
  549.               int 10h                       ;clear region
  550.               ret
  551. ClearScreen   endp
  552.  
  553. ;-----------------------------------------------------------------------------
  554. ;ClearRegion clears the lower portion of the display.
  555. ;-----------------------------------------------------------------------------
  556. ClearRegion   proc near
  557.               mov ch,textrow                ;define upper left corner
  558.               xor cl,cl
  559.               jmp short clear1
  560. ClearRegion   endp
  561. ;
  562. code          ends
  563.               end begin
  564.